/*
 * Copyright WelinkSoft Ltd. (c) 2020.
 */

package com.xj.util;

/**
 * Created by Administrator on 2017/6/26.
 */

import org.apache.commons.net.ftp.*;
import org.apache.log4j.Logger;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;


public class FtpdUtil  {
    public static Logger logger = Logger.getLogger(FtpdUtil.class);


    public static FTPClient ftpLogin(String strIp, int port, String user, String password) {
        boolean isLogin = false;
        FTPClientConfig ftpClientConfig = new FTPClientConfig("WINDOWS");
        ftpClientConfig.setServerTimeZoneId(TimeZone.getDefault().getID());
        ftpClientConfig.setDefaultDateFormatStr("yyyy-MM-dd HH:mm:ss");
        ftpClientConfig.setServerLanguageCode("zh");
      System.setProperty("https.protocols", "TLSv1,TLSv1.1,TLSv1.2");
       FTPClient ftpClient = new FTPClient();
       ftpClient.configure(ftpClientConfig);
       //    this.ftpClient.setControlEncoding("UTF-8");
         ftpClient.setControlEncoding("GBK");
            ftpClient.setDataTimeout(60000);       //设置传输超时时间为60秒
            ftpClient.setConnectTimeout(60000);       //连接超时为60秒
        //    ftpClient.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));

         try {
            if(!ftpClient.isConnected()) {
                if (port > 0) {
                    ftpClient.connect(strIp, port);
                } else {
                    ftpClient.connect(strIp);
                }
            }
            // FTP服务器连接回答
            int reply = ftpClient.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftpClient.disconnect();
                logger.info("登录FTP服务失败！");

            }
            Boolean r = ftpClient.login(user, password);
            logger.info("登录结果:" + r);
            // 设置传输协议
            ftpClient.enterLocalPassiveMode();   //被动模式
            //    this. ftpClient.enterLocalActiveMode();    //主动模式
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
         //   this.ftpClient.execPROT("P");
            logger.info("恭喜" + user + "成功登陆FTP服务器");
             ftpClient.setBufferSize(1024 * 2);
             ftpClient.setDataTimeout(30 * 1000);
        } catch (Exception e) {
            logger.info(user + "登录FTP服务失败！" + e.getMessage());
            logger.error("",e);
             return  null;
        }

        return ftpClient;
    }


    public  static  void ftpLogOut(FTPClient ftpClient) {
        if (null != ftpClient && ftpClient.isConnected()) {
            try {
                boolean reuslt = ftpClient.logout();// 退出FTP服务器
                if (reuslt) {
                    logger.info("成功退出服务器");
                }
            } catch (IOException e) {
                logger.info("退出FTP服务器异常！" + e.getMessage());
                logger.error("",e);
            } finally {
                try {
                    ftpClient.disconnect();// 关闭FTP服务器的连接
                } catch (IOException e) {
                    logger.info("关闭FTP服务器的连接异常！");
                    logger.error("",e);
                }
            }
        }
    }


    public   static  boolean uploadFile(FTPClient ftpClient,File localFile, String romotUpLoadePath) {
        BufferedInputStream inStream = null;
        boolean success = false;
        try {
            Boolean  result=   ftpClient.changeToParentDirectory();
            logger.info("准备上传文件,切换到ParentDirectory:"+result);
            logger.info("当前工作目录:"+  ftpClient.printWorkingDirectory());
            // 改变工作路径
            result=  ftpClient.changeWorkingDirectory(romotUpLoadePath);
            logger.info("切换工作目录：" + romotUpLoadePath + ",结果:" + result);
            inStream = new BufferedInputStream(new FileInputStream(localFile));
            logger.info(localFile.getName() + ",开始上传");
            success = ftpClient.storeFile(localFile.getName(), inStream);
            if (success == true) {
                logger.info(localFile.getName() + ",上传成功");
                return success;
            }
        } catch (FileNotFoundException e) {
            logger.info(localFile + "未找到");
            logger.error("{}",e);
        } catch (IOException e) {
            logger.error("IOException,", e);
        } finally {
            if (inStream != null) {
                try {
                    inStream.close();
                } catch (IOException e) {
                    logger.error("", e);
                }
            }
        }
        return success;
    }



    public    static  boolean downloadFile(FTPClient ftpClient,    String remoteFileName, String localDires,
                                String remoteDownLoadPath) {
        String strFilePath = localDires + remoteFileName;
        BufferedOutputStream outStream = null;
        boolean success = false;
        try {
            ftpClient.changeWorkingDirectory(remoteDownLoadPath);
            outStream = new BufferedOutputStream(new FileOutputStream(
                    strFilePath));
            logger.info(remoteFileName + "开始下载....");
            success = ftpClient.retrieveFile(remoteFileName, outStream);
            if (success == true) {
                logger.info(remoteFileName + "成功下载到" + strFilePath);
                return success;
            }
        } catch (Exception e) {
            logger.error("",e);
            logger.info(remoteFileName + "下载失败");
        } finally {
            if (null != outStream) {
                try {
                    outStream.flush();
                    outStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        if (success == false) {
            logger.info(remoteFileName + "下载失败!!!");
        }
        return success;
    }


    public   static   boolean uploadDirectory(FTPClient ftpClient,String localDirectory,
                                   String remoteDirectoryPath) {
        File src = new File(localDirectory);
        try {
            if(!remoteDirectoryPath.endsWith("/")){
                remoteDirectoryPath=remoteDirectoryPath+"/";
            }
            ftpClient.makeDirectory(remoteDirectoryPath);
            remoteDirectoryPath = remoteDirectoryPath + src.getName() + "/";
            ftpClient.makeDirectory(remoteDirectoryPath);
        } catch (IOException e) {
            logger.info(remoteDirectoryPath + "目录创建失败");

            logger.error("{}",e);
        }
        try {
            ftpClient.changeWorkingDirectory(remoteDirectoryPath);
        }catch (Exception err){
            logger.error("{}",err);
        }

        File[] allFile = src.listFiles();
        for (int currentFile = 0; currentFile < allFile.length; currentFile++) {
            if (!allFile[currentFile].isDirectory()) {
                String srcName = allFile[currentFile].getPath().toString();
                uploadFile(ftpClient,    new File(srcName), remoteDirectoryPath);
            }
        }
        for (int currentFile = 0; currentFile < allFile.length; currentFile++) {
            if (allFile[currentFile].isDirectory()) {
                // 递归
                uploadDirectory(ftpClient,   allFile[currentFile].getPath().toString(),
                        remoteDirectoryPath);
            }
        }
        return true;
    }



    public   static     boolean downLoadDirectory(FTPClient ftpClient,String localDirectoryPath,String remoteDirectory) {
        try {
            String fileName = new File(remoteDirectory).getName();
            localDirectoryPath = localDirectoryPath + fileName + File.separator;
            new File(localDirectoryPath).mkdirs();
            FTPFile[] allFile = ftpClient.listFiles(remoteDirectory);
            for (int currentFile = 0; currentFile < allFile.length; currentFile++) {
                if (!allFile[currentFile].isDirectory()) {
                    downloadFile(ftpClient,allFile[currentFile].getName(),localDirectoryPath, remoteDirectory);
                }
            }
            for (int currentFile = 0; currentFile < allFile.length; currentFile++) {
                if (allFile[currentFile].isDirectory()) {
                    String strremoteDirectoryPath = remoteDirectory + "/"+ allFile[currentFile].getName();
                    downLoadDirectory(ftpClient,localDirectoryPath,strremoteDirectoryPath);
                }
            }
        } catch (IOException e) {
            logger.info("下载文件夹失败");
            logger.error("",e);
            return false;
        }
        return true;
    }

        public    static  String removeDirectoryALLFile(FTPClient ftpClient,String  pathName) {
            if(pathName.endsWith("/")){
                pathName=pathName.substring(0,pathName.length()-1);
            }
            try {
                FTPFile[] files = ftpClient.listFiles(pathName);
                if (null != files && files.length > 0) {
                    for (FTPFile file : files)
                    {
                        if (file.isDirectory()) {
                          removeDirectoryALLFile(ftpClient,pathName + "/" + file.getName());
                            // 切换到父目录，不然删不掉文件夹
                            ftpClient.changeWorkingDirectory(pathName.substring(0, pathName.lastIndexOf("/")));
                            ftpClient.removeDirectory(pathName);
                     } else{
                          if (!ftpClient.deleteFile(pathName + "/" + file.getName())){
                                return "删除指定文件" + pathName + "/" + file.getName() + "失败!";
                            }
                        }
                    }
                }
                // 切换到父目录，不然删不掉文件夹
                ftpClient.changeWorkingDirectory(pathName.substring(0, pathName.lastIndexOf("/")));
                ftpClient.removeDirectory(pathName);
            }
            catch (IOException e){
                logger.error("删除指定文件夹" + pathName + "失败：" + e);
                e.printStackTrace();
                return "删除指定文件夹" + pathName + "失败：" + e;
            }
          return "SUCCESS";
        }



    public   static    Map changeDirectory(Map input) throws Exception {
        FTPClient client = (FTPClient) input.get("ftpClient");
        if (null == client || !client.isConnected()) {
            throw new Exception("参数错误：ftpClient为null或没有连接。");
        }

        String directory = (String) input.get("directory");
        if (null == directory || directory.trim().equals("")) {
            directory = File.separator;//默认切换至主目录
        }

        Map output = new HashMap();
        boolean result = false;
        try {
            result = client.changeWorkingDirectory(directory);
        } catch (FTPConnectionClosedException e) {
            logger.info("FTP连接已经被关闭。");
            output.put("success", "false");
            output.put("ftpClient", client);

            return output;
        } catch (IOException e) {
            logger.info("切换工作目录存在IO错误");

            output.put("success", "false");
            output.put("ftpClient", client);

            return output;
        }

        output.put("success", String.valueOf(result));
        output.put("ftpClient", client);

        return output;
    }

    public   static   boolean    renameFile(FTPClient ftpClient,String  from,  String  to)  {

        boolean result = false;
        try {
            result = ftpClient.rename(from, to);
        } catch (IOException e) {
            logger.info("[pub.FtpUtil.renameFile] 删除远程文件失败，原因：" + e);
            result = false;
            logger.error("",e);
        }
        return true;
    }



    public  static    boolean isDirExist(FTPClient ftpClient,String fileName, String  remoteDirectory)
    {
        try {
            FTPFile[] fs = ftpClient.listFiles(remoteDirectory);
            for (int i = 0; i < fs.length; i++) {
                FTPFile ff = fs[i];
                if (ff.getName().equals(fileName)) {
                    return true; // 如果存在返回 正确信号
                }
            }
        }catch (Exception e)
        {
            logger.error("", e);
        }
        return false; // 如果不存在返回错误信号
    }


    public  static  String deleteHisoryFile(FTPClient ftpClient,String  pathName,String  day) {
          if(!pathName.endsWith("/")){
            pathName=pathName+"/";
        }
        List<String>  ftpFileList=new ArrayList<>();
        ftpFileList=  getFtpfileList(ftpClient,pathName,Integer.valueOf(day),ftpFileList);

       try{
            if (null != ftpFileList && ftpFileList.size() > 0) {
                for (String filename : ftpFileList)
                {
                    String  today= DateUtils.formatDate(new Date(), "yyyyMMdd");
                    if(filename.endsWith("/")){
                        filename=filename.substring(0,filename.length()-1);
                    }
                    int   pos=filename.lastIndexOf("/");
                   String  parentFold=filename.substring(0,pos)+"/";
                    FTPFile[]     files = ftpClient.listFiles(parentFold);
                     for(int i=0;i<files.length;i++) {
                         FTPFile ftpFile = files[i];
                         String  ftpFileName = ftpFile.getName();
                           if(ftpFileName.equals(today)){
                               removeDirectoryALLFile(ftpClient,filename);
                           }
                     }
                }
            }
        }
        catch (Exception e){
            logger.error("删除指定文件夹" + pathName + "失败：" + e);
            e.printStackTrace();
            return "删除指定文件夹" + pathName + "失败：" + e;
        }
        return "SUCCESS";
    }

public  static   List<String>  getFtpfileList(FTPClient ftpClient,String  remotePath,int  day, List<String> list){
    try {
        FTPFile[]  fold1=     ftpClient.listFiles(remotePath);
        for(int i=0;i<fold1.length;i++){
            FTPFile ftpFile=fold1[i];
            String  filename=ftpFile.getName();
            Calendar  calendar=Calendar.getInstance();
            calendar.add(Calendar.DATE,day*(-1));
            Date date=calendar.getTime();
            SimpleDateFormat sd=new SimpleDateFormat("yyyyMMdd");
            String  histdate=sd.format(date);
            if(filename.equals("20200318")){
                System.out.println(filename);
            }
            if(filename.matches("20[0-9]{6}")&&filename.compareTo(histdate)<0){
                list.add(remotePath+filename+"/");
           }else  if(ftpFile.isDirectory()){
                getFtpfileList(ftpClient,remotePath+filename+"/",day,list);
            }

        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    return   list;
}




    public  void main(String[] args) throws IOException {

      FTPClient  ftpClient=ftpLogin("192.168.32.128", 221, "user1", "1");

     //   上传文件夹
      uploadDirectory(ftpClient, "D:/111", "/1");
        File f=new File("C:\\Users\\Administrator\\Desktop\\培训内容.docx");
         uploadFile(ftpClient, f, "/Adapter/pepsi");
     //    下载文件夹
         downLoadDirectory(ftpClient, "C://Users//Administrator//Desktop//", "/1/111");
        deleteHisoryFile(ftpClient, "/1/111","0");
      //  下载文件
          downloadFile(ftpClient, "培训内容.docx", "C://Users//Administrator//Desktop//pepsi//", "/Adapter/pepsi");
     //   删除文件
       //       ftp.deleteFile("/Adapter/pepsi/培训内容.docx");
     //   修改文件
             renameFile(ftpClient, "/Adapter/pepsi/readme.txt", "/Adapter/pepsi/readme1.txt");
   //     判断文件夹中是否含有文件
            Boolean  result= isDirExist(ftpClient,"readme1.txt", "/Adapter/pepsi");
    //    删除文件
            removeDirectoryALLFile(ftpClient, "/1/111/");
        ftpLogOut(ftpClient);
    }

}
